/**
 * 弹出层管理组件
 * @Author: Malphite
 * @Date: 2022-10-16
 */
("use strict");
(function () {
  var doc = window.document;
  var jsPath = doc.currentScript
    ? doc.currentScript.src
    : (function () {
      var js = doc.scripts,
        last = js.length - 1,
        src;
      for (var i = last; i > 0; i--) {
        if (js[i].readyState === "interactive") {
          src = js[i].src;
          break;
        }
      }
      return src || js[last].src;
    })();

  var basePath = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);

  layui.extend({
    binder: basePath + "binder",
    vform: basePath + "vform",
  });

})();

const welcome = {
  id: "welcome",
  type: 1,
  name: "关于windows",
  area: ['540px', '530px'],
  offset: ['40px', '260px'],
  icon: "&#xe609;",
  content: `
  <div class="layui-layer-windows-welcome">
    <div class="welcome-title" >
      <div class = "welcome-title-icon">
        <i class="layui-icon ">&#xe609;</i>
      </div>
      <div class = "welcome-title-text">
        <span>windows3</span>
      </div>
      <div class = "welcome-title-msg">
        欢迎使用
      </div>
      <div class = "welcome-title-label">
        发布时间:2022-10-23
      </div>
    </div>
    <div class="welcome-body" >
      <blockquote class="layui-elem-quote">
        文档: https://www.yuque.com/docs/share/56d5bfa0-f1a0-4a76-acf4-1c044aaca2a7?# 《windows3》
      </blockquote>
      <blockquote class="layui-elem-quote">
        gitee: https://gitee.com/my_sword_will_drink_blood/layui_binder
      </blockquote>
      <blockquote class="layui-elem-quote">
        意见: https://gitee.com/my_sword_will_drink_blood/layui_binder/issues
      </blockquote>
      <div class="layui-form-item" style="text-align:right">
        <div class="layui-inline">
          <button class="layui-btn" type="button" title="关闭">关闭</button> 
        </div>
      </div>
    </div>
  </div>`,
  success(layero, index) {
    layero.find('.layui-btn').on('click', function (e) {
      e.stopPropagation();
      e.preventDefault();
      layui.layer.close(index);
    });
  },
};

layui.define(["jquery", "layer", "binder"], function (exports) {
  var $ = layui.jquery;
  let config = {
    constant: {
      // 是否展示操作栏
      DISPLAY_BAR: true,
      // 是否展示卡贴
      DISPLAY_TIPS: false,
      DISPLAY_MULTIPLE_LAYER: false,
      ENABLE_FIT_POSITON: true,
      DYNAMIC_OWNER: "",
      DYNAMIC_STARTER: false,
      HEADERS_ID: "LAY_app_tabsheader",
      MAX_INDEX: 19891014,
      TOP_INDEX: 0,
      HIDE: "layui-hide",
      INTERNAL_INDEX: 0,
      RADIUS: 30,
      CONTAINER_ID: "layui-windows-bottom",
      SINGLETON: "property",
      METHOD_AUTOEXEC_NAME: "run",
      MIN_CLASSNAME: "layui-min-header",
      MAX_CLASSNAME: "layui-max-header",
      CONTAINER_TIPS_CLASSNAME: "layui-windows-tip",
      BASE_WINDOWS_TOP_OFFSET: 70,
      BASE_WINDOWS_BOTTOM_OFFSET: 85,
      BASE_WINDOWS_LEFT_OFFSET: 10,
      BASE_WINDOWS_TOP_DIRECTION: "DOWN",
      BASE_WINDOWS_LEFT_DIRECTION: "RIGHT",
      BASE_WINDOWS_OFFSET: 30,
      BASE_WINDOWS_WIDTH: 380,
    },
    base: {
      username: "Malphite",
      livelyPool: [],
      hover: {},
      hoverPool: [],
      flip: {
        list: [],
        map: {},
        show: false,
        size: 6,
        now: 0,
      },
      assign: [],
      TEMP_ASSIGN_WINDOW: {
        id: 0,
        width: 0,
        height: 0,
        top: 0,
        left: 0,
      },
      menuVisible: false,
      tipsIcon: {
        visible: false,
        x: 0,
        y: 0,
        id: "",
      },
      tipsSource: [
        {
          id: 1,
          name: welcome.name,
          icon: welcome.icon,
          link: welcome.id,
          temp: false,
        }
      ],
    },
    temp: {
      windowsMap: {},
      windowsAssignMap: {},
      resizeFn: {},
    },
    pageDescribe: {
      welcome: welcome,
    },
    pageMultiple: {},
  };
  let constant = {
    VERSION: "3.0.0",
    FIRST_LOADING: false,
    MANAGE_CONTAINER_ID: "layui-layer-layerManage",
    MIN_OFFSET_TOP: 50,
    MIN_OFFSET_LEFT: 50,
    MIN_TIPS_AREA_LEFT: 370,
    MIN_TIPS_AREA_BOTTOM: 450,
    TIPS_AREA_FLAG: false,
    TIPS_AREA_ICON: "&#xe62a;",
    TIPS_INSERT_FLAG: false,
    MOVE_BASE_WINDOW: {},
    MOVE_ASSIGN_WINDOW: {},
    SYNC_ASSIGN_FLAG: false,
    SHAKE_WINDOW_OPTION: {
      AWAKE: false,
      X: 0,
      Y: 0,
      DIRECTION: "",
      ACTION: [],
    },
    MOVEING_ASSIGN_WINDOW: {},
    MOVEING_FLIP_WINDOW: {
      flag: false,
      X: 0,
      Y: 0,
    },
  };
  let $body = $("body");
  let rollPage = {
    left: function (root, index) {
      let tabsLeft = parseFloat(root.css("left"));
      if (!tabsLeft && tabsLeft <= 0) return;
      let prefLeft = -(tabsLeft + root.outerWidth());
      if (prefLeft >= 0) return root.css("left", 0);
      root.children("li").each(function (index, item) {
        let li = $(item),
          left = li.position().left;
        if (left >= prefLeft) {
          root.css("left", -left);
          return false;
        }
      });
    },
    auto: function (root, index) {
      let tabsLeft = parseFloat(root.css("left"));
      let thisLi = root.find('[lay-id="' + index + '"]');
      if (!thisLi[0]) return;
      let thisLeft = thisLi.position().left;
      if (thisLeft < -tabsLeft) {
        return root.css("left", -thisLeft);
      }
      if (thisLeft + thisLi.outerWidth() >= root.outerWidth() - tabsLeft) {
        let subLeft =
          thisLeft + thisLi.outerWidth() - (root.outerWidth() - tabsLeft);
        root.children("li").each(function (i, item) {
          let li = $(item),
            left = li.position().left;
          if (left + tabsLeft > subLeft) {
            root.css("left", -left);
            return false;
          }
        });
      }
    },
    right: function (root, index) {
      let tabsLeft = parseFloat(root.css("left"));
      root.children("li").each(function (index, item) {
        let li = $(item),
          left = li.position().left;
        if (left + li.outerWidth() >= root.outerWidth() - tabsLeft) {
          root.css("left", -left);
          return false;
        }
      });
    },
  };
  let REFLACT = {
    getWindow: (key) => config.pageDescribe[key].parent,
    getTopIndex: () => config.constant.TOP_INDEX,
    setTopIndex: (key) => (config.constant.TOP_INDEX = key),
    getMaxIndex: () => config.constant.MAX_INDEX,
    setMaxIndex: (index) => (config.constant.MAX_INDEX = index),
    getInternalIndex: () => config.constant.INTERNAL_INDEX++,
    getBaseWindowsWidth: () => config.constant.BASE_WINDOWS_WIDTH,
    getBaseWindowsTop: () => config.constant.BASE_WINDOWS_TOP_OFFSET,
    getBaseWindowsOffset: () => config.constant.BASE_WINDOWS_OFFSET,
    getBaseWindowsLeft: () => config.constant.BASE_WINDOWS_LEFT_OFFSET,
    getBaseWindowsBottom: () => config.constant.BASE_WINDOWS_BOTTOM_OFFSET,
    getWindowsVerticalDirection: () =>
      config.constant.BASE_WINDOWS_TOP_DIRECTION,
    setWindowsVerticalDirection: (v) =>
      (config.constant.BASE_WINDOWS_TOP_DIRECTION = v),
    getWindowsHorizontalDirection: () =>
      config.constant.BASE_WINDOWS_LEFT_DIRECTION,
    setWindowsHorizontalDirection: (v) =>
      (config.constant.BASE_WINDOWS_LEFT_DIRECTION = v),
    getSingletonKey: () => config.constant.SINGLETON,
    getDisplayMultipleKey: () => config.constant.DISPLAY_MULTIPLE_LAYER,
    getInvokeName: () => config.constant.METHOD_AUTOEXEC_NAME,
    getFitPosition: () => config.constant.ENABLE_FIT_POSITON,
    getHideClass: () => config.constant.HIDE,
    getMaxClass: () => config.constant.MAX_CLASSNAME,
    getMinClass: () => config.constant.MIN_CLASSNAME,
    getWindowsMap(key) {
      return key ? config.temp.windowsMap[key] : config.temp.windowsMap;
    },
    deletetWindowsMap(key) {
      delete config.temp.windowsMap[key];
    },
    getPageDescribe(key) {
      return key ? config.pageDescribe[key] : config.pageDescribe;
    },
    deletePageDescribe(key) {
      delete config.pageDescribe[key];
    },
    getPageMultiple(key) {
      return key ? config.pageMultiple[key] : config.pageMultiple;
    },
    deletePageMultiple(group, key) {
      delete config.pageMultiple[group][key];
    },
    getResizeFn(key) {
      return key ? config.temp.resizeFn[key] : config.temp.resizeFn;
    },
    deleteResizeFn(key) {
      delete config.temp.resizeFn[key];
    },
  };
  let PROXY = {
    getActionContainer() {
      return this.parent.find("#" + config.constant.HEADERS_ID);
    },
    getMarkofMax() {
      return $("." + REFLACT.getMaxClass());
    },
    getTipsContainer() {
      return this.parent.find("." + config.constant.CONTAINER_TIPS_CLASSNAME);
    },
  };
  layui.binder.extend({
    name: "windows",
    data: config.base,
    template: `
    <div>
      <div id="${config.constant.CONTAINER_ID}" class = "${config.constant.MAX_CLASSNAME}">
        <div class="layui-windows-menu" title = "打开菜单" @click = "showMenu">
          <i class="layui-icon ">&#xe609;</i>
        </div>
        <div class="layui-windows-group">
          <div class="layui-icon layadmin-tabs-control layui-icon-prev" @click="rollPageLeft"></div>
          <div class="layui-icon layadmin-tabs-control layui-icon-next" @click="rollPageRight"></div>
          <div class="layui-tab">
            <ul class="layui-tab-title" id="${config.constant.HEADERS_ID}" v-each="livelyPool" mark="arr" key = "index" @mousedown = "startFlipEvent">
              <li :class="layui-tab-title-{{{{arr.select}}}}" lay-id="#{arr.id}"  @mouseenter="showWindowTip"  @mouseleave="hideWindowTip"  @click="setGroupTop(#{arr.id})" >
                <i class="layui-icon">#{!arr.icon ? "" : arr.icon}</i> {{{{arr.name}}}}
              </li>
            </ul>
          </div>
        </div>
        <div class="layui-windows-notice" title = "关闭全部" @click = "closeAll" @mouseenter="appendHover(0)" @mouseleave="removeHover(0)" @mousemove = "moveHover(0)">
          <i class="layui-icon layui-icon-close"></i>
        </div>
        <!-- 预览小窗口 -->
        <div class="${config.constant.CONTAINER_TIPS_CLASSNAME}"  @mouseenter="hoverTip"  @mouseleave="hideWindowTip" v-each="hoverPool" mark="arr" key = "id"  >
          <div class = "layui-windows-tips"  @mouseenter="appendHover(#{arr.id})" @mouseleave="removeHover(#{arr.id})" @mousemove = "moveHover(#{arr.id})"  wid = "#{arr.id}" @click="setHoverTop(#{arr.id})">
            <i class="layui-icon layui-icon-close" @click="closeFromTip" title = "关闭" ></i>
            <div>#{arr.name}</div>
          </div>  
        </div>
        <!-- 3d flip -->
        <div class = "layui-windows-flip" :class = "layui-windows-flip-{{flip.show}}" >
          <i class="layui-icon layui-icon-close"   @click = "closeFlip"  title = "关闭"></i>
          <i class="layui-icon layui-icon-prev" @click = "moveFlipRight"></i>
          <i class="layui-icon layui-icon-next" @click = "moveFlipLeft"></i>
        </div>
        <!-- 窗口合并 临时跟踪方框 -->
        <div class = "layui-windows-track" :class = "trackClass" :style = "trackStyle"></div>
      </div>
      <!-- 窗口合并 方框组-->
      <div class = "layui-windows-assign" v-each = "assign" mark = "arr" key = "id" >
        <div class = "layui-windows-assign-body" :class = "layui-windows-assign-body-{{{{arr.show}}}}" :style = "z-index:{{{{arr.zIndex}}}};width:{{{{arr.width}}}}px;height:{{{{arr.height}}}}px;top:{{{{arr.top}}}}px;left:{{{{arr.left}}}}px"  @mousedown = "setAssignWindowTop({{index}})" >
          <div class = "layui-windows-assign-title" assignid = "{{index}}" @mousedown = "mousedownEvent" >{{{{arr.name}}}}
            <div class = "layui-windows-assign-title-min">
              <i class="layui-icon layui-icon-subtraction" assignid = "{{index}}"  @click = "minAssignWindow"  title = "最小化"></i>
            </div>
            <div class = "layui-windows-assign-title-close">
              <i class="layui-icon layui-icon-close"  assignid = "{{index}}"  @click = "closeAssignWindow"  title = "关闭"></i>
            </div>
          </div>
          <div class = "layui-windows-assign-border"></div>
        </div>
      </div>
      <!-- 窗口卡贴 -->
      <div class = "layui-windows-tile-lively-icon" 
        :class = "layui-windows-tile-lively-icon-{{tipsIcon.visible}}" 
        :style = "top: {{tipsIcon.y}}px;left: {{tipsIcon.x}}px;">
        <i class="layui-icon ">&#xe62a;</i>
      </div>
      <div class = "layui-windows-tile" :class = "layui-windows-tile-{{menuVisible}}" @click = "stopCloseTips" >
        <i class="layui-icon layui-windows-tile-main-icon">&#xe609;</i>
        <div class="layui-windows-tile-main-text">{{username}}</div>
        <blockquote class="layui-elem-quote">窗口卡贴</blockquote>
        <div class="layui-form-item" style = "margin:0">
          <div class = "layui-notice-menu" @mousemove = "fitMenuStyle"  v-each="tipsSource" mark = "arr" key = "id">
            <div class = "layui-notice-menu-group" :lay-link = "{{arr.link}}"  tipkey = "{{index}}"  @click = "clickSubMenu(#{arr.link})">
              <div class = "layui-notice-menu-title">
                <i class="layui-icon layui-menu-icon">#{arr.icon}</i>
              </div>
              <div class = "layui-notice-menu-text">
                #{arr.name}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>  
    `,
    watchs: {
      hover(value) {
        if (value.id) {
          this.tabsBody(value.id)
            .removeClass("layui-windows-preview")
            .addClass("layui-windows-preview");
          $("body")
            .removeClass("layui-windows-preview")
            .addClass("layui-windows-preview");
        } else if (value.id == 0) {
          $("body")
            .removeClass("layui-windows-preview")
            .addClass("layui-windows-preview");
        } else {
          $(".layui-windows-preview").removeClass("layui-windows-preview");
        }
      },
      livelyPool() {
        if (this.flip.show) this.closeFlip();
        this.parent.find(".select-tip-fixed").removeClass("select-tip-fixed");
      },
      hoverPool(value) {
        if (value && value.length > 0) {
          let $this = this.parent
            .find("#" + config.constant.HEADERS_ID)
            .find('[lay-id="' + this.$data.hoverPool[0].groupid + '"]');
          let $target = this.parent.find(
            "." + config.constant.CONTAINER_TIPS_CLASSNAME
          );
          if (!$this.get(0)) return;
          let left = $this.get(0).getBoundingClientRect().left;
          let width = $this.outerWidth();
          let finalLeft = left - ($target.width() - width) / 2;
          $target.css({ left: finalLeft < 0 ? 0 : finalLeft + "px" });
        }
      },
    },
    computeds: {
      trackClass() {
        return this.TEMP_ASSIGN_WINDOW.id ? "" : "layui-hide";
      },
      trackStyle() {
        return `top:${this.TEMP_ASSIGN_WINDOW.top}px;left:${this.TEMP_ASSIGN_WINDOW.left}px;width:${this.TEMP_ASSIGN_WINDOW.width}px;height:${this.TEMP_ASSIGN_WINDOW.height}px;`;
      },
    },
    methods: {
      rollPageLeft() {
        rollPage.left(PROXY.getActionContainer.call(this));
      },
      rollPageRight() {
        rollPage.right(PROXY.getActionContainer.call(this));
      },
      rollPageAuto(index) {
        rollPage.auto(PROXY.getActionContainer.call(this), index);
      },
      tabsBody(index) {
        return REFLACT.getWindow(index);
      },
      setTop(index = config.constant.TOP_INDEX) {
        let that = this;
        if (!index) return;
        if (that.flip.show) that.closeFlip();
        let wConfig = REFLACT.getPageDescribe(index);
        let zIndex = REFLACT.getMaxIndex();
        _.each(
          _.sortBy(REFLACT.getWindowsMap(), (u) => -u.updateTime),
          function (v) {
            that.tabsBody(v.id).css("z-index", --zIndex);
            REFLACT.getPageDescribe(v.id).nowIndex = zIndex;
          }
        );
        _.each(that.livelyPool, function (v) {
          let childernflag = false;
          _.each(v.children, function (v1) {
            if (v1 == index) childernflag = true;
          });
          v.select = childernflag;
        });
        REFLACT.getWindowsMap(index).updateTime = new Date();
        that
          .tabsBody(index)
          .css("z-index", REFLACT.getMaxIndex())
          .removeClass(REFLACT.getHideClass());
        wConfig.nowIndex = REFLACT.getMaxIndex();
        wConfig.show = true;
        if (wConfig.min) that.restore(index);
        REFLACT.setTopIndex(index);
        that.rollPageAuto(index);
        _.each(that.assign, function (v) {
          let showFlag =
            REFLACT.getPageDescribe(v.fromid).show ||
            REFLACT.getPageDescribe(v.toid).show;
          if (!showFlag) {
            v.show = false;
          } else {
            v.show = true;
            if (REFLACT.getPageDescribe(v.fromid).min) that.restore(v.fromid);
            if (REFLACT.getPageDescribe(v.toid).min) that.restore(v.toid);
            let maxIndex = Math.max(
              REFLACT.getPageDescribe(v.fromid).nowIndex,
              REFLACT.getPageDescribe(v.toid).nowIndex
            );
            v.zIndex = maxIndex;
            REFLACT.getPageDescribe(v.fromid).nowIndex = maxIndex;
            REFLACT.getWindow(v.fromid).css("z-index", maxIndex);
            REFLACT.getPageDescribe(v.toid).nowIndex = maxIndex;
            REFLACT.getWindow(v.toid).css("z-index", maxIndex);
          }
        });
      },
      resize: function (id, fn) {
        if (REFLACT.getResizeFn(id)) {
          $(window).off("resize", REFLACT.getResizeFn(id));
          REFLACT.deleteResizeFn(id);
        }
        if (!_.isFunction(fn)) return;
        REFLACT.getResizeFn().id = function () {
          debounce(fn, { args: [id] });
        };
        $(window).on("resize", REFLACT.getResizeFn(id));
      },
      open(opt = {}, data = {}) {
        if (opt.type == "3" || opt.type == "4") return opt;
        if (opt.shade) return opt;
        if (opt.skin) return opt;
        if (opt.ignore) return opt;
        if (_.isString(opt)) {
          let _id = "";
          if (/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(opt)) {
            _id = "TEMP_" + REFLACT.getInternalIndex();
            opt = { id: _id, name: opt, type: 1, temp: true };
          } else {
            opt = REFLACT.getPageDescribe(opt)
              ? REFLACT.getPageDescribe(opt)
              : { id: opt, name: opt, type: 1, temp: false };
          }
        } else {
          if (opt.type === undefined) return opt;
        }
        if (!opt.id) {
          opt.id = "TEMP_" + REFLACT.getInternalIndex();
          opt.temp = true;
        }
        if (!REFLACT.getPageDescribe(opt.id)) {
          REFLACT.getPageDescribe()[opt.id] = _.assign({
            id: opt.id,
            type: opt.type || 1,
            content: opt.content || "",
            shade: opt.shade || 0,
            shift: opt.shift || opt.anim || 1,
            fixed: opt.fixed || false,
            maxmin: opt.maxmin || true,
            name: opt.name,
            porperty: opt.porperty || "singleton",
            snapshoot: opt.snapshoot || null,
            moudle: opt.moudle || "",
            assign: opt.assign || false,
            assignBy: opt.assignBy || "",
            temp: opt.temp,
          }, opt);
        } else {
          _.assign(REFLACT.getPageDescribe(opt.id), opt);
        }
        let wConfig = REFLACT.getPageDescribe(opt.id);
        if (wConfig.index) {
          this.setTop(opt.id);
          _.isFunction(data) && data(wConfig);
          return wConfig.index;
        }
        // let position = {} ;
        // if(REFLACT.getFitPosition())
        //   position = this.position(data.area);
        var multipleFlag =
          wConfig.temp !== true &&
          (wConfig.porperty === REFLACT.getSingletonKey() ||
            REFLACT.getDisplayMultipleKey() === true);
        if (multipleFlag) {
          let key = data.id || data.code || 0;
          if (REFLACT.getPageMultiple(opt.id)) {
            if (key && REFLACT.getPageMultiple(opt.id)[key]) {
              this.setTop(REFLACT.getPageMultiple(opt.id)[key]);
              let sConfig = REFLACT.getPageDescribe(
                REFLACT.getPageMultiple(opt.id)[key]
              );
              _.isFunction(data) && data(sConfig);
              return sConfig.index;
            }
          } else {
            REFLACT.getPageMultiple()[opt.id] = {};
          }
          let _index = "TEMP_" + REFLACT.getInternalIndex();
          if (key) {
            REFLACT.getPageMultiple(opt.id)[key] = _index;
          }
          REFLACT.getPageDescribe()[_index] = _.assign({}, wConfig, {
            id: _index,
            name:
              data && data.name ? wConfig.name + "-" + data.name : wConfig.name,
            topid: opt.id,
            porperty: "child",
          });
          wConfig = REFLACT.getPageDescribe(_index);
        }
        if (!wConfig.name) wConfig.name = wConfig.id;
        if (!wConfig.title)
          wConfig.title = `${wConfig.icon == undefined
              ? ""
              : `<i class="layui-icon">${wConfig.icon}</i>&nbsp;&nbsp;&nbsp;`
            }<b>${wConfig.name}</b>`;
        let option = _.assign(
          {
            type: 1,
            shade: 0,
            shift: 1,
            fixed: false,
            maxmin: true,
            skin: "layui-layer-windows",
            // offset: [position.top + "px", position.left + "px"],
            // area: [position.width + "px", position.height + "px"],
          },
          wConfig
        );
        let that = this;
        option.success = function (layero, layerid) {
          that.success.call(that, layero, layerid, wConfig.id);
          if (wConfig.moudle && _.isString(wConfig.moudle)) {
            layui.use(wConfig.moudle, function () {
              if (layui[wConfig.moudle][REFLACT.getInvokeName()])
                layui[wConfig.moudle][REFLACT.getInvokeName()](
                  layero,
                  layerid,
                  wConfig.id,
                  data,
                  wConfig
                );
              if (layui[wConfig.moudle].resize)
                that.resize(wConfig.id, layui[wConfig.moudle].resize);
              _.isFunction(data) && data(wConfig);
            });
          } else {
            _.isFunction(data) && data(wConfig);
          }
          wConfig.success &&
            wConfig.success(layero, layerid, wConfig.id, data, wConfig);
        };
        option.end = function () {
          that.end.call(that, wConfig.id);
          if (wConfig.moudle) {
            if (layui[wConfig.moudle].destroy) {
              layui[wConfig.moudle].destroy(wConfig.id, wConfig);
            }
            if (wConfig.VM) {
              wConfig.VM.$destroy();
              wConfig.VM = null;
            }
            if (layui[wConfig.moudle].resize) {
              that.resize(wConfig.id);
            }
          }
          wConfig.end && wConfig.end(wConfig.id);
        };
        option.cancel = function (layerid, layero) {
          if (that.flip.show) that.closeFlip();
          if (window.event) window.event.stopPropagation();
          PROXY.getMarkofMax().removeClass(REFLACT.getMinClass());
          if (wConfig.cancel && _.isFunction(wConfig.cancel)) {
            wConfig.cancel(layerid, layero, function () {
              that.beforeDestroy(wConfig.id);
            });
            return false;
          }
          that.beforeDestroy(wConfig.id);
          return false;
        };
        option.full = function (index) {
          if (that.flip.show) that.closeFlip();
          PROXY.getMarkofMax()
            .removeClass(REFLACT.getMinClass())
            .addClass(REFLACT.getMinClass());
          wConfig.full && wConfig.full(index);
          if (REFLACT.getResizeFn(wConfig.id)) {
            REFLACT.getResizeFn(wConfig.id).call(this);
          }
        };
        option.restore = function (index) {
          PROXY.getMarkofMax().removeClass(REFLACT.getMinClass());
          wConfig.restore && wConfig.restore(index);
          if (REFLACT.getResizeFn(wConfig.id)) {
            REFLACT.getResizeFn(wConfig.id).call(this);
          }
        };
        option.resizing = function (layero) {
          if (that.flip.show) that.closeFlip();
          wConfig.resizing && wConfig.resizing(layero);
          if (REFLACT.getResizeFn(wConfig.id)) {
            REFLACT.getResizeFn(wConfig.id).call(this);
          }
        };
        if (!wConfig.url && !option.content)
          option.content = "<div>" + option.name + "</div>";
        return option;
      },
      success(layero, index, id) {
        let wConfig = REFLACT.getPageDescribe(id);
        wConfig.index = index;
        wConfig.parent = layero;
        wConfig.min = false;
        wConfig.show = true;
        REFLACT.setMaxIndex(parseInt(layero.css("zIndex")));
        let parentid = wConfig.topid || id;
        let parentname = REFLACT.getPageDescribe(parentid).name;
        REFLACT.getWindowsMap()[id] = {
          id: id,
          name: wConfig.name,
          select: false,
          updateTime: new Date(),
        };
        let parentflag = false;
        _.each(this.livelyPool, function (v) {
          if (v.id == parentid) {
            parentflag = true;
            let childflag = false;
            _.each(v.children, function (v1) {
              if (v1 == id) childflag = true;
            });
            if (!childflag) v.children.push(id);
          }
        });
        if (!parentflag) {
          let list = _.cloneDeep(this.livelyPool);
          list.push({
            index: REFLACT.getInternalIndex(),
            id: parentid,
            name: parentname,
            select: false,
            assign: 0,
            icon: wConfig.icon,
            children: [id],
          });
          this.livelyPool = list;
        }
        let that = this;
        layero
          .off("click", ".layui-layer-min")
          .on("click", ".layui-layer-min", function (e) {
            if (that.flip.show) that.closeFlip();
            e.stopPropagation();
            layero
              .removeClass(REFLACT.getHideClass())
              .addClass(REFLACT.getHideClass());
            wConfig.min = true;
            wConfig.show = false;
            wConfig.select = false;
            if (REFLACT.getTopIndex() == id) REFLACT.setTopIndex(0);
            that.afterMin(id);
          });
        if (!wConfig.click) {
          wConfig.click = true;
          layero.on("mousedown", function () {
            that.setTop(id);
          });
          layero.on("mousedown", ".layui-layer-title", function (e) {
            constant.MOVE_BASE_WINDOW = {
              id: id,
              offsetTop: parseInt(layero.css("top")),
              offsetLeft: parseInt(layero.css("left")),
              currentWidth: layero.width(),
              currentHeight: layero.height(),
            };
          });
          layero.on("mouseup", ".layui-layer-title", function (e) {
            constant.MOVE_BASE_WINDOW = {};
          });
        }
        this.setTop(id);
      },

      end(id) {
        let wConfig = REFLACT.getPageDescribe(id);
        if (wConfig.topid) {
          let index = wConfig.topid;
          if (!REFLACT.getPageMultiple(index))
            REFLACT.getPageMultiple()[index] = {};
          let key = null;
          _.each(REFLACT.getPageMultiple(index), function (v, k) {
            if (v == id) {
              key = k;
              return false;
            }
          });
          if (key) REFLACT.deletePageMultiple(index, key);
        }
        if (REFLACT.getWindowsMap(id)) REFLACT.deletetWindowsMap(id);
        if (wConfig.assignBy) {
          this.removeGroupPool(id);
        } else {
          this.resetLivelyPool(id);
        }
        wConfig.click = false;
        if ("child" == wConfig.porperty) {
          REFLACT.deletePageDescribe(id);
        } else {
          wConfig.index = null;
          wConfig.parent = null;
          wConfig.assignBy = "";
        }
      },
      resetLivelyPool(id) {
        let parentid = REFLACT.getPageDescribe(id).topid || id;
        let list = _.cloneDeep(this.livelyPool);
        _.remove(list, function (v) {
          if (v.id != parentid) return false;
          _.remove(v.children, (v1) => v1 == id);
          return v.children.length == 0;
        });
        REFLACT.setTopIndex(0);
        this.livelyPool = list;
        let hoverList = _.cloneDeep(this.hoverPool);
        _.remove(hoverList, (v) => v.id == id);
        this.hoverPool = hoverList;
      },
      removeGroupPool(id) {
        let that = this;
        let wConfig = REFLACT.getPageDescribe(id);
        let key = wConfig.assignBy;
        let temp_list = _.cloneDeep(that.assign);
        _.remove(temp_list, function (v) {
          if (v.id === key) {
            REFLACT.getPageDescribe(v.fromid).assignBy = "";
            REFLACT.getPageDescribe(v.toid).assignBy = "";
            if (v.fromid === id) {
              that.close(v.toid);
            }
            if (v.toid === id) {
              that.close(v.fromid);
            }
            return true;
          }
          return false;
        });
        that.assign = temp_list;
        let list = _.cloneDeep(that.livelyPool);
        _.remove(list, (v) => v.id === key);
        REFLACT.setTopIndex(0);
        that.livelyPool = list;
        let hoverList = _.cloneDeep(that.hoverPool);
        _.remove(hoverList, (v) => v.id == id);
        that.hoverPool = hoverList;
      },
      beforeDestroy(id) {
        return this.doCloseLayer(id);
      },
      doCloseLayer(id) {
        let _index = REFLACT.getPageDescribe(id).index;
        _index && layui.layer.close(_index);
        REFLACT.getPageDescribe(id).index = null;
        REFLACT.getPageDescribe(id).parent = null;
      },
      _restore(id) {
        let _index = REFLACT.getPageDescribe(id).index;
        if (_index) {
          try {
            layui.layer.restore(_index);
          } catch (error) { }
        }
      },
      restore(id) {
        let wConfig = REFLACT.getPageDescribe(id);
        if (wConfig.index) {
          try {
            layui.layer.restore(wConfig.index);
          } catch (error) { }
          wConfig.min = false;
          wConfig.select = true;
          wConfig.show = true;
          REFLACT.getWindow(id).removeClass(REFLACT.getHideClass());
        }
      },
      min(id) {
        let wConfig = REFLACT.getPageDescribe(id);
        let _index = config.pageDescribe[id].index;
        if (wConfig.index && !wConfig.min) {
          layui.layer.min(wConfig.index);
          wConfig.min = true;
          wConfig.select = false;
          wConfig.show = false;
          REFLACT.getWindow(id)
            .removeClass(REFLACT.getHideClass())
            .addClass(REFLACT.getHideClass());
          this.afterMin(id);
        }
      },
      afterMin(id) {
        let wConfig = REFLACT.getPageDescribe(id);
        if (!wConfig) return;
        if (!wConfig.assign || wConfig.assignBy == "") return;
        let assignID = wConfig.assignBy;
        let that = this;
        _.each(that.assign, function (v) {
          if (v.id == assignID) {
            v.show = false;
            let toid = v.fromid;
            if (toid == id) toid = v.toid;
            let sConfig = REFLACT.getPageDescribe(toid);
            if (sConfig && !!sConfig.index && !sConfig.min) that.min(toid);
          }
        });
      },
      close(id) {
        this.beforeDestroy(id);
      },
      minAll() {
        let _this = this;
        _.each(REFLACT.getWindowsMap(), (v, k) => _this.min(k));
      },
      closeAll() {
        let _this = this;
        _.each(REFLACT.getWindowsMap(), (v, k) => _this.close(k));
      },
      showWindowTip(e) {
        let $this = $(e.target);
        let that = this;
        this.parent.find(".li-select-tip").removeClass("li-select-tip");
        $this.addClass("li-select-tip");
        let id = $this.attr("lay-id");
        let $target = PROXY.getTipsContainer.call(that);
        $target
          .removeClass("no-select-tip")
          .removeClass("select-tip-flag")
          .addClass("select-tip-flag")
          .addClass("no-select-tip");
        _.each(that.livelyPool, function (v) {
          if (v.id == id) {
            let templist = [];
            that.$data.hoverPool = [];
            _.each(v.children, function (v1) {
              templist.push({
                id: REFLACT.getWindowsMap(v1).id,
                name: REFLACT.getWindowsMap(v1).name,
                groupid: id,
              });
            });
            that.$data.hoverPool = templist;
            let left = $this.get(0).getBoundingClientRect().left;
            let width = $this.outerWidth();
            let finalLeft = left - ($target.width() - width) / 2;
            $target.css({ left: finalLeft < 0 ? 0 : finalLeft + "px" });
            $target.removeClass("select-tip").addClass("select-tip");
            setTimeout(() => $target.removeClass("no-select-tip"), 300);
          }
        });
      },
      hoverTip() {
        let $target = PROXY.getTipsContainer.call(this);
        if ($target.hasClass("no-select-tip")) return;
        if (!$target.hasClass("select-tip-flag"))
          $target.addClass("select-tip-flag");
      },
      hideWindowTip() {
        let _this = this;
        let $target = PROXY.getTipsContainer.call(this);
        $target.removeClass("select-tip-flag");
        setTimeout(function () {
          if (!$target.hasClass("select-tip-flag")) {
            $target.removeClass("select-tip");
            _this.parent.find(".li-select-tip").removeClass("li-select-tip");
            $target.removeClass("no-select-tip").addClass("no-select-tip");
            setTimeout(() => $target.removeClass("no-select-tip"), 300);
          }
        }, 300);
      },
      closeFromTip(e) {
        e.stopPropagation();
        e.preventDefault();
        let id = $(e.target).parent().attr("wid");
        this.close(id);
        let $target = PROXY.getTipsContainer.call(this);
        if (!$target.hasClass("no-select-tip"))
          $target.addClass("no-select-tip");
        this.hover = {};
        setTimeout(function () {
          $target.removeClass("no-select-tip");
        }, 300);
      },
      setHoverTop(id) {
        this.setTop(id);
        this.hover = {};
        let $parent = PROXY.getTipsContainer.call(this);
        $parent
          .removeClass("select-tip")
          .removeClass("select-tip-flag")
          .addClass("no-select-tip");
        setTimeout(() => $parent.removeClass("no-select-tip"), 300);
      },
      setGroupTop(id) {
        let _this = this;
        _.each(_this.livelyPool, function (v) {
          if (v.id == id) {
            let $parent = PROXY.getTipsContainer.call(_this);
            if (v.children.length == 1 || (v.assign && v.assign == 1)) {
              let child = v.children[0];
              if (
                REFLACT.getTopIndex() == child &&
                !REFLACT.getPageDescribe(child).min &&
                REFLACT.getPageDescribe(child).show
              ) {
                _this.min(v.children[0]);
              } else {
                _this.setTop(v.children[0]);
              }
              _this.hover = {};
              $parent
                .removeClass("select-tip")
                .removeClass("select-tip-flag")
                .addClass("no-select-tip");
              setTimeout(() => $parent.removeClass("no-select-tip"), 300);
            } else {
              if (window.event) window.event.stopPropagation();
              if ($parent.hasClass("select-tip-fixed")) {
                $parent
                  .removeClass("select-tip-fixed")
                  .removeClass("select-tip")
                  .removeClass("select-tip-flag")
                  .addClass("no-select-tip");
                setTimeout(() => $parent.removeClass("no-select-tip"), 300);
              } else {
                $parent.addClass("select-tip-fixed");
              }
            }
          }
        });
      },
      appendHover(id) {
        if (0 == id) {
          this.hover = { id: 0 };
          return;
        }
        let $target = PROXY.getTipsContainer.call(this);
        if ($target.hasClass("no-select-tip")) return;
        let wConfig = REFLACT.getPageDescribe(id);
        this.tabsBody(id).css("z-index", REFLACT.getMaxIndex() + 1);
        if (!!wConfig.min) this._restore(id);
        if (!wConfig.show)
          this.tabsBody(id).removeClass(REFLACT.getHideClass());
        this.hover = { id: id };
      },
      moveHover(id) {
        if (0 == id) {
          this.hover = { id: 0 };
          return;
        }
        let $target = PROXY.getTipsContainer.call(this);
        if ($target.hasClass("no-select-tip")) return;
        if (this.hover.id != id) {
          this.hover.id && this.removeHover(this.hover.id);
          this.appendHover(id);
        }
      },
      removeHover(id) {
        if (0 == id) {
          this.hover = {};
          return;
        }
        if (this.hover.id == id) {
          let wConfig = REFLACT.getPageDescribe(id);
          this.tabsBody(id).css("z-index", wConfig.nowIndex);
          if (!!wConfig.min) this.min(id);
          if (!wConfig.show)
            this.tabsBody(id)
              .removeClass(REFLACT.getHideClass())
              .addClass(REFLACT.getHideClass());
          this.hover = {};
        }
      },
      clickSubMenu(key) {
        if (key && "looking" != key) layui.layer.open(key);
        this.menuVisible = false;
      },
      setAssignWindowTop(id) {
        let that = this;
        _.each(that.assign, function (v) {
          if (v.id == id) that.setTop(v.fromid);
        });
      },
      assignWindowTest(fromid, top, left, width, height) {
        if (constant.SYNC_ASSIGN_FLAG) return;
        let temp_config = {
          id: 0,
          width: 0,
          height: 0,
          top: 0,
          left: 0,
        };
        _.each(REFLACT.getPageDescribe(), function (v, k) {
          let _flag =
            v.parent &&
            v.id != fromid &&
            v.assign === true &&
            !v.assignBy &&
            v.show;
          if (_flag) {
            let [_top, _left, _width, _height] = [
              parseInt(v.parent.css("top")),
              parseInt(v.parent.css("left")),
              v.parent.width(),
              v.parent.height(),
            ];
            let temp_top = Math.abs(top - _top);
            let temp_out_left =
              _left > left ? _left - left - width : left - _left - _width;
            if (
              temp_top <= constant.MIN_OFFSET_TOP &&
              temp_out_left <= constant.MIN_OFFSET_LEFT
            ) {
              let ftop =
                _top > top
                  ? top - constant.MIN_OFFSET_TOP
                  : _top - constant.MIN_OFFSET_TOP;
              let fleft =
                _left > left
                  ? left - constant.MIN_OFFSET_LEFT
                  : _left - constant.MIN_OFFSET_LEFT;
              let fright =
                Math.max(left + width, _left + width) +
                constant.MIN_OFFSET_LEFT;
              let fwidth = fright - fleft;
              let fheight =
                Math.max(height, _height) + constant.MIN_OFFSET_TOP * 2;
              constant.MOVE_ASSIGN_WINDOW = {
                id: k,
                offsetTop: _top,
                offsetLeft: _left,
                currentWidth: _width,
                currentHeight: _height,
              };
              temp_config = {
                id: k,
                width: fwidth,
                height: fheight,
                top: ftop,
                left: fleft,
              };
            }
          }
        });
        this.TEMP_ASSIGN_WINDOW = temp_config;
      },
      assignWindow(temp_config, fromid, top, left, width, height) {
        let that = this;
        if (constant.SYNC_ASSIGN_FLAG) {
          that.TEMP_ASSIGN_WINDOW = {
            id: 0,
            width: 0,
            height: 0,
            top: 0,
            left: 0,
          };
          return;
        }
        let _name =
          REFLACT.getPageDescribe(fromid).name +
          "&" +
          REFLACT.getPageDescribe(temp_config.id).name;
        let temp_assign = {
          id: "ASSIGN_" + REFLACT.getInternalIndex(),
          name: _name,
          show: true,
          zIndex: REFLACT.getMaxIndex(),
          top: temp_config.top + constant.MIN_OFFSET_TOP,
          left: temp_config.left + constant.MIN_OFFSET_LEFT / 4,
          width:
            constant.MOVE_ASSIGN_WINDOW.currentWidth +
            width +
            constant.MIN_OFFSET_LEFT,
          height: temp_config.height - constant.MIN_OFFSET_TOP / 2 - 50,
        };
        if (left > temp_config.left) {
          temp_assign.fromid = temp_config.id;
          temp_assign.toid = fromid;
          temp_assign.from = {
            id: constant.MOVE_ASSIGN_WINDOW.id,
            top: constant.MOVE_ASSIGN_WINDOW.offsetTop,
            left: constant.MOVE_ASSIGN_WINDOW.offsetLeft,
            width: constant.MOVE_ASSIGN_WINDOW.currentWidth,
            height: constant.MOVE_ASSIGN_WINDOW.currentHeight,
          };
          temp_assign.to = {
            id: fromid,
            top: top,
            left: left,
            width: width,
            height: height,
          };
        } else {
          temp_assign.toid = temp_config.id;
          temp_assign.fromid = fromid;
          temp_assign.to = {
            id: constant.MOVE_ASSIGN_WINDOW.id,
            top: constant.MOVE_ASSIGN_WINDOW.offsetTop,
            left: constant.MOVE_ASSIGN_WINDOW.offsetLeft,
            width: constant.MOVE_ASSIGN_WINDOW.currentWidth,
            height: constant.MOVE_ASSIGN_WINDOW.currentHeight,
          };
          temp_assign.from = {
            id: fromid,
            top: top,
            left: left,
            width: width,
            height: height,
          };
        }
        REFLACT.getWindow(temp_assign.fromid).css({
          top: temp_assign.top + 50 + "px",
        });
        REFLACT.getWindow(temp_assign.toid).css({
          top: temp_assign.top + 50 + "px",
        });

        REFLACT.getWindow(temp_assign.fromid).css({
          left: temp_assign.left + constant.MIN_OFFSET_LEFT / 2 + "px",
        });
        REFLACT.getWindow(temp_assign.toid).css({
          left:
            temp_assign.left +
            constant.MIN_OFFSET_LEFT / 2 +
            temp_assign.from.width +
            "px",
        });
        REFLACT.getWindow(temp_assign.fromid).css({
          height: temp_assign.height - constant.MIN_OFFSET_TOP / 2 - 50 + "px",
        });
        REFLACT.getWindow(temp_assign.toid).css({
          height: temp_assign.height - constant.MIN_OFFSET_TOP / 2 - 50 + "px",
        });
        REFLACT.getWindow(temp_assign.fromid).find(".layui-layer-title").hide();
        REFLACT.getWindow(temp_assign.toid).find(".layui-layer-title").hide();
        REFLACT.getWindow(temp_assign.fromid)
          .find(".layui-layer-resize")
          .hide();
        REFLACT.getWindow(temp_assign.toid).find(".layui-layer-resize").hide();
        REFLACT.getWindow(temp_assign.fromid).removeClass(
          "layui-layer-windows"
        );
        REFLACT.getWindow(temp_assign.toid).removeClass("layui-layer-windows");
        REFLACT.getWindow(temp_assign.fromid)
          .find(".layui-layer-setwin")
          .hide();
        REFLACT.getWindow(temp_assign.toid).find(".layui-layer-setwin").hide();
        REFLACT.getPageDescribe(temp_assign.fromid).assignBy = temp_assign.id;
        REFLACT.getPageDescribe(temp_assign.toid).assignBy = temp_assign.id;
        let temp_list = _.cloneDeep(that.assign);
        temp_list.push(temp_assign);
        that.assign = temp_list;
        let from_parentid =
          REFLACT.getPageDescribe(temp_assign.fromid).topid ||
          temp_assign.fromid;
        let to_parentid =
          REFLACT.getPageDescribe(temp_assign.toid).topid || temp_assign.toid;
        let temp_livelyPool = _.cloneDeep(this.livelyPool);
        let temp_res_livelyPool = [];
        _.each(temp_livelyPool, function (v) {
          if (v.id == from_parentid || v.id == to_parentid) {
            let temp_children = _.cloneDeep(v.children);
            let temp_res_children = [];
            _.each(temp_children, function (v1) {
              if (v1 == temp_assign.fromid || v1 == temp_assign.toid) {
              } else {
                temp_res_children.push(v1);
              }
            });
            v.children = temp_res_children;
            if (v.children.length != 0) {
              temp_res_livelyPool.push(v);
            }
          } else {
            temp_res_livelyPool.push(v);
          }
        });
        temp_res_livelyPool.push({
          index: REFLACT.getInternalIndex(),
          id: temp_assign.id,
          name: temp_assign.name,
          icon: "",
          select: true,
          assign: 1,
          children: [temp_assign.fromid, temp_assign.toid],
        });
        this.livelyPool = temp_res_livelyPool;
        that.TEMP_ASSIGN_WINDOW = {
          id: 0,
          width: 0,
          height: 0,
          top: 0,
          left: 0,
        };
        // if(REFLACT.getPageDescribe(temp_assign.fromid).VM && REFLACT.getPageDescribe(temp_assign.toid).VM){
        //   REFLACT.getPageDescribe(temp_assign.fromid).VM.linkWindow(REFLACT.getPageDescribe(temp_assign.toid).VM);
        // }
        that.setTop(temp_assign.fromid);
      },
      shakeWindowTest(id, X, Y) {
        if (!constant.SHAKE_WINDOW_OPTION.AWAKE)
          return this.awakeShakeWindow(X, Y);
        if (
          Math.abs(constant.SHAKE_WINDOW_OPTION.X - X) >
          constant.MIN_OFFSET_LEFT
        )
          return this.awakeShakeWindow(X, Y);
        if (constant.SHAKE_WINDOW_OPTION.Y == Y) return;
        let direction = constant.SHAKE_WINDOW_OPTION.Y > Y ? "UP" : "DOWN";
        if (direction != constant.SHAKE_WINDOW_OPTION.DIRECTION) {
          constant.SHAKE_WINDOW_OPTION.DIRECTION = direction;
          constant.SHAKE_WINDOW_OPTION.ACTION.push(direction);
        }
        if (constant.SHAKE_WINDOW_OPTION.ACTION.length >= 4) {
          let _this = this;
          _.each(REFLACT.getWindowsMap(), function (v, k) {
            if (k != id) _this.min(k);
          });
          _this.sleepShakeWindow();
        }
      },
      awakeShakeWindow(X, Y) {
        constant.SHAKE_WINDOW_OPTION.AWAKE = true;
        constant.SHAKE_WINDOW_OPTION.X = X;
        constant.SHAKE_WINDOW_OPTION.Y = Y;
        constant.SHAKE_WINDOW_OPTION.DIRECTION = "";
        constant.SHAKE_WINDOW_OPTION.ACTION = [];
      },
      sleepShakeWindow() {
        constant.SHAKE_WINDOW_OPTION.AWAKE = false;
        constant.SHAKE_WINDOW_OPTION.X = 0;
        constant.SHAKE_WINDOW_OPTION.Y = 0;
        constant.SHAKE_WINDOW_OPTION.DIRECTION = "";
        constant.SHAKE_WINDOW_OPTION.ACTION = [];
      },
      tipsWindowTest(fromid, top, left) {
        if (!config.constant.DISPLAY_BAR || !config.constant.DISPLAY_TIPS)
          return;
        let topid = REFLACT.getPageDescribe(fromid).topid || fromid;
        let flag = false;
        _.each(this.tipsSource, function (v) {
          if (v.link == topid && !v.temp) flag = true;
        });
        if (flag) return;
        if (
          left < constant.MIN_TIPS_AREA_LEFT &&
          $body.height() - top < constant.MIN_TIPS_AREA_BOTTOM
        ) {
          constant.TIPS_AREA_FLAG = true;
          this.menuVisible = true;
          this.tipsIcon.visible = true;
          this.tipsIcon.x = left - 35;
          this.tipsIcon.y = top - 35;
          this.tipsIcon.id = fromid;
          this.windowsTipsMove(left, top);
          constant.SYNC_ASSIGN_FLAG = true;
        } else {
          constant.TIPS_AREA_FLAG = false;
          this.menuVisible = false;
          this.tipsIcon.visible = false;
          constant.SYNC_ASSIGN_FLAG = false;
        }
      },
      tipsWindow() {
        if (!config.constant.DISPLAY_BAR || !config.constant.DISPLAY_TIPS)
          return;
        if (constant.TIPS_AREA_FLAG && this.tipsIcon.id) {
          let wConfig = REFLACT.getPageDescribe(this.tipsIcon.id);
          let temp_list = _.sortBy(_.cloneDeep(this.tipsSource), (v) => v.id);
          let tips_list = [];
          let flag = false;
          let index = 1;
          _.each(temp_list, function (v) {
            if (v.temp) flag = true;
            tips_list.push(_.assign({}, v, { id: index++, temp: false }));
          });
          if (!flag)
            tips_list.push({
              id: index++,
              name: wConfig.name,
              icon: wConfig.icon || constant.TIPS_AREA_ICON,
              link: wConfig.topid || wConfig.id,
              temp: false,
            });
          this.tipsSource = tips_list;
          let w_config = REFLACT.getPageDescribe(constant.MOVE_BASE_WINDOW.id);
          w_config.parent.css(
            "top",
            constant.MOVE_BASE_WINDOW.offsetTop + "px"
          );
          w_config.parent.css(
            "left",
            constant.MOVE_BASE_WINDOW.offsetLeft + "px"
          );
        } else {
          if (constant.TIPS_INSERT_FLAG) {
            let temp_list = _.cloneDeep(this.tipsSource);
            let tips_list = [];
            _.each(temp_list, function (v) {
              if (!v.temp) tips_list.push(v);
            });
            this.tipsSource = tips_list;
          }
        }
        constant.TIPS_INSERT_FLAG = false;
        constant.TIPS_AREA_FLAG = false;
        this.tipsIcon.visible = false;
        this.tipsIcon.id = "";
        this.menuVisible = false;
      },
      showMenu(e) {
        e.stopPropagation();
        e.preventDefault();
        if (!config.constant.DISPLAY_BAR || !config.constant.DISPLAY_TIPS) {
          this.menuVisible = false;
        } else {
          this.menuVisible = !this.menuVisible;
        }
      },
      stopCloseTips(e) {
        e.stopPropagation();
        e.preventDefault();
      },
      fitMenuStyle(e) {
        let x = e.clientX;
        let y = e.clientY;
        this.parent.find(".layui-notice-menu-group").each(function () {
          let $this = $(this);
          let left = $this.get(0).getBoundingClientRect().left;
          let top = $this.get(0).getBoundingClientRect().top;
          let width = $this.outerWidth();
          let height = $this.outerHeight();
          let pointX = left + width / 2;
          let pointY = top + height / 2;
          let offsetX = parseInt(x - pointX);
          let offsetY = parseInt(y - pointY);
          let offset =
            Math.abs(offsetX) > Math.abs(offsetY)
              ? Math.abs(offsetX)
              : Math.abs(offsetY);
          let extra = Math.floor(offset / (width / 2)) * 3;
          let boxShadow = `${-offsetX}px ${-offsetY}px 10px ${-(
            offset + extra
          )}px #FCFCFC inset `;
          $this.css({ boxShadow: boxShadow });
        });
      },
      windowsTipsMove(x, y) {
        let key = 0;
        this.parent.find(".layui-notice-menu-group").each(function () {
          let $this = $(this);
          let left = $this.get(0).getBoundingClientRect().left;
          let top = $this.get(0).getBoundingClientRect().top;
          let width = $this.outerWidth();
          let height = $this.outerHeight();
          if (x > left && x - left < width) {
            if (y > top && y - top < height) {
              key = $this.attr("tipkey");
            }
          }
        });
        if (this.tipsIcon.visible && this.tipsIcon.id && key)
          this.updateWindowsTips(key);
      },
      updateWindowsTips(key) {
        constant.TIPS_INSERT_FLAG = true;
        let wConfig = REFLACT.getPageDescribe(this.tipsIcon.id);
        let temp_list = _.sortBy(_.cloneDeep(this.tipsSource), (v) => v.id);
        let tips_list = [];
        let tips_list2 = [];
        let index = 1;
        _.each(temp_list, function (v) {
          if (index == key)
            tips_list.push({
              id: index++,
              name: wConfig.name,
              icon: wConfig.icon || constant.TIPS_AREA_ICON,
              link: wConfig.topid || wConfig.id,
              temp: true,
            });
          if (!v.temp) {
            tips_list.push(_.assign({}, v, { id: index++ }));
            tips_list2.push(_.assign({}, v, { id: index++ }));
          }
        });
        this.tipsSource = tips_list2;
        this.tipsSource = tips_list;
      },
      getFlipList() {
        let res = [];
        let allList = _.sortBy(REFLACT.getWindowsMap(), (u) => -u.updateTime);
        if (allList.length == 0) return res;
        let index = this.flip.now;
        let key =
          this.flip.size > allList.length ? allList.length : this.flip.size;
        if (index < 0) index = (index % key) + key;
        index = index % key;
        if (allList.length < index + key) allList = allList.concat(allList);
        _.each(allList, function (v, k) {
          if (k >= index) {
            res.push({
              id: v.id,
              name: v.name,
            });
          }
        });
        res = res.slice(0, key);
        let $this = $body.find(".layui-windows-flip");
        let left = $this.get(0).getBoundingClientRect().left;
        let right = $this.get(0).getBoundingClientRect().right;
        let top = $this.get(0).getBoundingClientRect().top;
        let bottom = $this.get(0).getBoundingClientRect().bottom;
        let size = this.flip.size < 8 ? 8 + 2 : this.flip.size + 2;
        let maxStepX = (right - left) / size;
        let totalLeft = right;
        let tempIndex = REFLACT.getMaxIndex();
        let that = this;
        $body
          .find(".layui-windows-flip-action")
          .removeClass("layui-windows-flip-action");
        _.each(res, function (v, k) {
          let root = REFLACT.getWindow(v.id);
          if (!that.flip.map[v.id]) {
            if (!!REFLACT.getPageDescribe(v.id).min) that._restore(v.id);
            if (!REFLACT.getPageDescribe(v.id).show)
              REFLACT.getWindow(v.id).removeClass(REFLACT.getHideClass());
            that.flip.map[v.id] = {
              offsetTop: parseInt(root.css("top")),
              offsetLeft: parseInt(root.css("left")),
              currentWidth: parseInt(root.width()),
              currentHeight: parseInt(root.height()),
              zIndex: root.css("z-index"),
              min: REFLACT.getPageDescribe(v.id).min,
              show: REFLACT.getPageDescribe(v.id).show,
            };
          }
          let scale = 0.8;
          let width = that.flip.map[v.id].currentWidth;
          let height = that.flip.map[v.id].currentHeight;
          let mTop = top;
          if (height > 700) scale *= parseFloat(700 / height);
          if (mTop + height * scale > bottom) mTop = bottom - height * scale;
          let stepX = width > maxStepX ? maxStepX : width;
          stepX = maxStepX;
          totalLeft -= stepX;
          root
            .removeClass("layui-windows-flip-action")
            .addClass("layui-windows-flip-action")
            .css({
              top: mTop + width * scale * 0.45 + "px",
              left: parseFloat(totalLeft) - width * scale * 0.45 - 100 + "px",
              zIndex: tempIndex--,
              transformOrigin: "left top",
              transition: "all 0.3s",
              transform: `
                  scale(${scale - k * 0.1}) 
                  rotateY(48deg) 
                  skewY(-19deg)
                `,
            });
        });
        return res;
      },
      closeFlip() {
        let that = this;
        _.each(that.flip.map, function (v, k) {
          let $parent = REFLACT.getWindow(k);
          if ($parent) {
            $parent
              .css({
                top: v.offsetTop + "px",
                left: v.offsetLeft + "px",
                winth: v.currentWidth + "px",
                height: v.currentHeight + "px",
                zIndex: v.zIndex,
                transform: "none",
                transition: "none",
              })
              .removeClass("layui-windows-flip-action");
            if (v.min) that.min(k);
            if (!v.show)
              $parent
                .removeClass(REFLACT.getHideClass())
                .addClass(REFLACT.getHideClass());
          }
        });
        this.flip.map = {};
        this.flip.show = false;
        this.flip.list = [];
        this.flip.now = 0;
        $body.removeClass("layui-windows-preview");
      },
      showFlip() {
        this.flip.show = true;
        this.flip.list = this.getFlipList();
        $body
          .removeClass("layui-windows-preview")
          .addClass("layui-windows-preview");
        if (this.flip.list.length == 0) this.closeFlip();
      },
      setTopFlip(e) {
        e.stopPropagation();
        e.preventDefault();
        let id = $(e.target).attr("flipid");
        if (id) {
          this.setTop(id);
          this.closeFlip();
        }
      },
      closeFlipPart(e) {
        e.stopPropagation();
        e.preventDefault();
        let id = $(e.target).attr("flipid");
        if (id) {
          this.close(id);
          let that = this;
          setTimeout(function () {
            let list = that.getFlipList();
            if (list.length == 0) that.closeFlip();
            that.flip.list = list;
          }, 600);
        }
      },
      moveFlipLeft() {
        this.parent
          .find(".layui-windows-flip")
          .removeClass("layui-windows-flip-reverse");
        this.flip.now++;
        this.flip.list = this.getFlipList();
        if (this.flip.list.length == 0) this.closeFlip();
      },
      moveFlipRight() {
        this.parent
          .find(".layui-windows-flip")
          .removeClass("layui-windows-flip-reverse")
          .addClass("layui-windows-flip-reverse");
        this.flip.now--;
        this.flip.list = this.getFlipList();
        if (this.flip.list.length == 0) this.closeFlip();
      },
      startFlipEvent(e) {
        e.stopPropagation();
        e.preventDefault();
        let [X, Y] = [e.clientX, e.clientY];
        constant.MOVEING_FLIP_WINDOW = {
          flag: true,
          X: X,
          Y: Y,
        };
      },
      mousedownEvent(e) {
        let id = $(e.target).attr("assignid");
        let [X, Y] = [e.clientX, e.clientY];
        constant.MOVEING_ASSIGN_WINDOW = {
          id: id,
          X: X,
          Y: Y,
        };
        e.preventDefault();
      },
      moveingAssignWindow(X, Y) {
        let [_offsetX, _offsetY] = [
          X - constant.MOVEING_ASSIGN_WINDOW.X,
          Y - constant.MOVEING_ASSIGN_WINDOW.Y,
        ];
        _.each(this.assign, function (v) {
          if (v.id == constant.MOVEING_ASSIGN_WINDOW.id) {
            v.top = v.top + _offsetY;
            let fromTop = REFLACT.getWindow(v.fromid).css("top");
            let toTop = parseInt(fromTop) + _offsetY;
            REFLACT.getWindow(v.fromid).css("top", toTop + "px");
            REFLACT.getWindow(v.toid).css("top", toTop + "px");

            v.left = v.left + _offsetX;
            let fromLeft = REFLACT.getWindow(v.fromid).css("left");
            let toLeft = parseInt(fromLeft) + _offsetX;
            REFLACT.getWindow(v.fromid).css("left", toLeft + "px");

            fromLeft = REFLACT.getWindow(v.toid).css("left");
            toLeft = parseInt(fromLeft) + _offsetX;
            REFLACT.getWindow(v.toid).css("left", toLeft + "px");
          }
        });
        constant.MOVEING_ASSIGN_WINDOW.X = X;
        constant.MOVEING_ASSIGN_WINDOW.Y = Y;
      },
      minAssignWindow(e) {
        e.stopPropagation();
        e.preventDefault();
        let that = this;
        let id = $(e.target).attr("assignid");
        _.each(that.assign, function (v) {
          if (v.id == id) that.min(v.fromid);
        });
      },
      closeAssignWindow(e) {
        e.stopPropagation();
        e.preventDefault();
        let that = this;
        let id = $(e.target).attr("assignid");
        _.each(that.assign, function (v) {
          if (v.id == id) that.close(v.fromid);
        });
      },
    },
    beforeDestroy() {
      this.closeAll();
    },
    mounted() {
      let that = this;
      if (!constant.FIRST_LOADING) {
        $body
          .on("mousemove", function (e) {
            if (windowsProxy && windowsProxy.notify()) {
              let [X, Y] = [e.clientX, e.clientY];
              if (constant.MOVE_BASE_WINDOW.id) {
                if (that.flip.show) that.closeFlip();
                let wConfig = REFLACT.getPageDescribe(
                  constant.MOVE_BASE_WINDOW.id
                );
                let $parent = wConfig.parent;
                let top = parseInt($parent.css("top"));
                let left = parseInt($parent.css("left"));
                let width = parseInt($parent.css("width"));
                let height = parseInt($parent.css("height"));
                that.shakeWindowTest(constant.MOVE_BASE_WINDOW.id, X, Y);
                if (wConfig.assign === true && !wConfig.assignBy) {
                  that.assignWindowTest(
                    constant.MOVE_BASE_WINDOW.id,
                    top,
                    left,
                    width,
                    height
                  );
                }
                if (wConfig.temp !== true) {
                  that.tipsWindowTest(constant.MOVE_BASE_WINDOW.id, Y, X);
                }
              }
              if (constant.MOVEING_ASSIGN_WINDOW.id) {
                that.moveingAssignWindow(X, Y);
              }
            }
          })
          .on("mouseup", function (e) {
            if (windowsProxy && windowsProxy.notify()) {
              if (constant.MOVE_BASE_WINDOW.id) {
                let wConfig = REFLACT.getPageDescribe(
                  constant.MOVE_BASE_WINDOW.id
                );
                let $parent = wConfig.parent;
                let top = parseInt($parent.css("top"));
                let left = parseInt($parent.css("left"));
                let width = parseInt($parent.css("width"));
                let height = parseInt($parent.css("height"));
                that.sleepShakeWindow();
                if (wConfig.assign === true && !wConfig.assignBy) {
                  if (!!that.TEMP_ASSIGN_WINDOW.id)
                    that.assignWindow(
                      that.TEMP_ASSIGN_WINDOW,
                      constant.MOVE_BASE_WINDOW.id,
                      top,
                      left,
                      width,
                      height
                    );
                }
                if (wConfig.temp !== true) {
                  that.tipsWindow();
                }
                constant.MOVE_BASE_WINDOW = {};
              }
              if (constant.MOVEING_ASSIGN_WINDOW.id)
                constant.MOVEING_ASSIGN_WINDOW = {
                  id: "",
                  X: 0,
                  Y: 0,
                };
              if (constant.MOVEING_FLIP_WINDOW.flag) {
                let [X, Y] = [e.clientX, e.clientY];
                if (
                  Math.abs(constant.MOVEING_FLIP_WINDOW.X - X) <
                  constant.MIN_OFFSET_LEFT
                ) {
                  if (
                    constant.MOVEING_FLIP_WINDOW.Y - Y >
                    constant.MIN_OFFSET_TOP
                  ) {
                    that.showFlip();
                  }
                }
                constant.MOVEING_FLIP_WINDOW = {
                  flag: false,
                  X: 0,
                  Y: 0,
                };
              }
            }
          });
        $body.on("click", function (e) {
          if (that.menuVisible) that.menuVisible = false;
          that.parent.find(".select-tip-fixed").removeClass("select-tip-fixed");
        });
      }
      if (!config.constant.DISPLAY_BAR)
        this.parent
          .find("#" + config.constant.CONTAINER_ID)
          .removeClass(config.constant.HIDE)
          .addClass(config.constant.HIDE);
    },
  });
  let windowsProxy = {
    wakeUp: function (option, list) {
      this.initConfig(option, list);
      this.initVm.apply(this);
      // 额外引入css
      // this.loadCss(this.initVm.apply(this));
    },
    notify: function () {
      return this.VM && this.VM.isAlive;
    },
    open: function () {
      return this.VM.windows.open.apply(this.VM.windows, arguments);
    },
    initConfig: function (option = {}, list = {}) {
      _.assign(config.constant, option);
      if (config.constant.DYNAMIC_OWNER)
        config.base.username = config.constant.DYNAMIC_OWNER;
      _.each(list, (v, k) => (config.pageDescribe[k] = v));
    },
    initVm: function () {
      let the_container = this;
      this.clear();
      $body.append(
        $(`
        <div id = "${constant.MANAGE_CONTAINER_ID}">
          <windows></windows>
        </div>
      `)
      );
      this.VM = layui.binder({
        el: "#" + constant.MANAGE_CONTAINER_ID,
        beforeDestroy() {
          $body.find("#" + constant.MANAGE_CONTAINER_ID).remove();
        },
        mounted() {
          this.windows.sleep = function () {
            the_container.clear();
          };
          if (config.constant.DYNAMIC_STARTER) {
            the_container.animation();
          }
        },
      });
    },
    clear: function () {
      if (this.VM && this.VM.isAlive) this.VM.$destroy();
      this.VM = null;
    },
    createContext: function () {
      $body.append(
        $(
          `<div class = "layui-windows-canvas-border"></div><canvas class = "layui-windows-canvas" id="myCanvas" width="240" height="280"></canvas>`
        )
      );
      let canvas = document.getElementById("myCanvas");
      this.context = canvas.getContext("2d");
      return this.context;
    },
    getContext: function () {
      if (!this.context) return this.createContext();
      return this.context;
    },
    painting: function (times) {
      let ctx = this.getContext();
      ctx.strokeStyle = "rgba(255,255,255)";
      ctx.lineWidth = 5;
      ctx.clearRect(0, 0, 240, 240);
      let [w, h] = [210, 40];
      ctx.beginPath();
      ctx.moveTo(w, h);
      if (times > 90) {
        let [_w, _h] = [w - 90 * 1.93, h + 90 * 1];
        ctx.lineTo(_w, _h);
        let _times = times - 90;
        ctx.lineTo(_w + _times * 2.74, _h + _times * 1);
      } else {
        ctx.lineTo(w - times * 1.93, h + times * 1);
      }
      ctx.stroke();
      ctx.closePath();
      ctx.beginPath();
      ctx.moveTo(w, h);
      if (times > 90) {
        let [_w, _h] = [w - 90 * 1.11, h + 90 * 1.28];
        ctx.lineTo(_w, _h);
        let _times = times - 90;
        ctx.lineTo(_w, _h + _times * 2.3);
      } else {
        ctx.lineTo(w - times * 1.11, h + times * 1.28);
      }
      ctx.stroke();
      ctx.closePath();
      ctx.beginPath();
      ctx.moveTo(w, h);
      if (times > 90) {
        let [_w, _h] = [w - 90 * 0.34, h + 90 * 1.53];
        ctx.lineTo(_w, _h);
        let _times = times - 90;
        ctx.lineTo(_w - _times * 2.98, _h - _times * 0.9);
      } else {
        ctx.lineTo(w - times * 0.34, h + times * 1.53);
      }
      ctx.stroke();
      ctx.closePath();
    },
    drawing: function () {
      let ctx = this.getContext();
      ctx.strokeStyle = "rgba(255,255,255)";
      ctx.lineWidth = 5;
      ctx.fillStyle = "rgba(255,255,255)";
      ctx.font = "24px orbitron";
      ctx.moveTo(0, 250);
      ctx.beginPath();
      ctx.fillText("windows " + constant.VERSION, 40, 250);
      ctx.restore();
      ctx.closePath();
    },
    action: function (i) {
      let that = this;
      if (!i) i = 0;
      that.painting(i);
      i++;
      if (i > 110) return;
      setTimeout(function () {
        that.action(i);
      }, 10);
    },
    animation: function () {
      let that = this;
      that.action();
      setTimeout(function () {
        that.drawing();
      }, 1500);
      setTimeout(function () {
        that.drawing();
      }, 2000);
      setTimeout(function () {
        $body.find(".layui-windows-canvas-border").remove();
        $body.find(".layui-windows-canvas").remove();
      }, 2600);
    },
  };
  let handler = {
    wakeUp: function (option, list) {
      return windowsProxy.wakeUp(option, list);
    },
    open: function () {
      return windowsProxy.open.apply(windowsProxy, arguments);
    },
    notify: function () {
      return windowsProxy.notify();
    },
    instance: function () {
      return windowsProxy;
    },
  };
  const openForever = layui.layer.open;
  layui.layer.open = function (deliver, args0, args1) {
    if (
      window.layui &&
      layui.windows &&
      layui.windows.notify &&
      layui.windows.notify()
    ) {
      var tempResult = layui.windows.open(deliver, args0, args1);
      if (/^\d+$/.test(String(tempResult))) return tempResult;
      deliver = tempResult;
    }
    return openForever(deliver);
  };
  layui.layer.wakeUp = function (option, list) {
    if (!window.layui) return console.warn('不支持在单layer组件下启用windows组件');
    layui.windows.wakeUp(option, list);
  };
  exports("windows", handler);
});
